home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / graphics / orbwhirl.arj / ORBWHIRL.C < prev    next >
C/C++ Source or Header  |  1993-07-30  |  12KB  |  356 lines

  1. //ORBWHIRL v1.0 by Marc Coram, compiled with Turbo C
  2. #include <graphics.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <conio.h>
  6. #include <malloc.h>
  7. #include <math.h>
  8. #include <dos.h>
  9. #include "svga256.h"
  10.  
  11. //A little annotation wouldn't kill me.
  12.  
  13. #define KCURVE -2.  //Defaults set here
  14. #define KPOINTS 100
  15. #define KTLENGTH 8
  16.  
  17. #define UP 0
  18. #define DOWN 1
  19. #define LEFT 2
  20. #define RIGHT 3
  21.  
  22. #define TEXT 0
  23. #define BIF 1
  24. #define HIDDEN 2
  25.  
  26. #define UNMAP(x) ((double)(x)/(double)(size>>2)-2.) //changes a screencoord (int) to its literal position
  27. #define MAP(x) (((x)+2.)*(size>>2))                 //changes a literal position (double) to its screencoord
  28. #define f(x) ((x)*(x)+CURVE)                        //the main iterative function
  29.  
  30. //I know... so I got a little out of control with defined macro functions
  31. #define LEFTORRIGHT(); if (*destp>*xp) *dirp=RIGHT; else *dirp=LEFT;
  32. #define UPORDOWN(); if (*destp>*yp) *dirp=DOWN; else *dirp=UP;
  33.  
  34. #define CLEARMAIN();  setviewport(0, 0, size, getmaxy(), 1);clearviewport();setviewport(0,0,getmaxx(),getmaxy(),1);
  35. #define CLEARPANEL(); setviewport(size, 0, getmaxx(), getmaxy(), 1);clearviewport();setviewport(0,0,getmaxx(),getmaxy(),1);
  36.  
  37. #define FREEMEM(); if (direction!=NULL) {free(direction);free(xcoordinate);free(ycoordinate);free(destination);free(nextx);if (trailx!=NULL) {farfree(trailx);farfree(traily);trailx=NULL;}} direction=NULL;
  38.  
  39.  
  40. int huge svgasetmode4(){return SVGA1024x768;}
  41. int huge svgasetmode3(){return SVGA800x600;}
  42. int huge svgasetmode2(){return SVGA640x480;}
  43. int huge svgasetmode1(){return SVGA640x400;}
  44. int huge svgasetmode0(){return  VGA320x200;}
  45. int huge (*svgamodep)();
  46.  
  47. void main(int argc,char *argv[])
  48. {
  49.  
  50. unsigned char far *direction, far *dirp;
  51. int far *xcoordinate, far *xp;
  52. int far *ycoordinate, far *yp;
  53. int far *destination, far *destp;
  54. double far *nextx, far *nxp;
  55. int huge *trailx=NULL, huge *tx, huge *txmax;
  56. int huge *traily,      huge *ty;
  57.  
  58. int size;
  59. int i,c=1;
  60. double x,dx;
  61. double CURVE=KCURVE;
  62. int POINTS=KPOINTS;
  63. int TLENGTH=KTLENGTH;
  64. int arg=0;
  65. int shift=0;
  66. int panel=TEXT;
  67. int obif=-1;
  68.  
  69. //Setup Video
  70. int gdriver, gmode, errorcode;
  71. svgamodep=svgasetmode0;
  72. if (argc>=2) switch(argv[1][0]) {
  73.     case 'A': case 'a': argc--;arg++;break;         //Choose Video
  74.     case 'B': case 'b': svgamodep=svgasetmode1;argc--;arg++;break;
  75.     case 'C': case 'c': svgamodep=svgasetmode2;argc--;arg++;break;
  76.     case 'D': case 'd': svgamodep=svgasetmode3;argc--;arg++;break;
  77.     case 'E': case 'e': svgamodep=svgasetmode4;argc--;arg++;break;
  78.     }
  79.  
  80. //Load command line arguments
  81. if (argc>4) {printf("\nInvalid command line\n");getch();goto exit;}
  82. if (argc>=2) CURVE=atof(argv[1+arg]);
  83. if (argc>=3) POINTS=atoi(argv[2+arg]);
  84. if (argc==4) TLENGTH=atoi(argv[3+arg]);
  85.  
  86. reinstall:
  87. installuserdriver("svga256",*svgamodep);
  88. gdriver=DETECT;
  89. initgraph(&gdriver, &gmode, "");
  90. errorcode = graphresult();
  91. if (errorcode != grOk)
  92. {
  93.     printf("Graphics error: %s\n", grapherrormsg(errorcode));
  94.     printf("Press any key to halt:");
  95.     getch();
  96.     goto exit;
  97. }
  98. size=(getmaxy()>>2)<<2;
  99.  
  100. redraw:
  101.  
  102. {//Set the palette
  103. double c,region,dc,top,pointct;
  104. if (TLENGTH==0) pointct=253;else pointct=POINTS;
  105. setrgbpalette(254,210,210,210);
  106. setrgbpalette(255,255,255,255);
  107. setcolor(255);
  108. settextjustify(CENTER_TEXT, CENTER_TEXT);
  109. outtextxy((int)(getmaxx()>>1),size>>1,"Setting Palette");
  110.  
  111. region=(pointct+1)/6.;if ((int)region) dc=63./(int)region;else dc=63.;top=region;
  112. for (i=1,c=0;i<top; i++,c+=dc) setrgbpalette(i,63 ,0  ,c  );top+=region;
  113. for (       ;i<top; i++,c-=dc) setrgbpalette(i,c  ,0  ,63 );top+=region;
  114. for (    c=0;i<top; i++,c+=dc) setrgbpalette(i,0  ,c  ,63 );top+=region;
  115. for (       ;i<top; i++,c-=dc) setrgbpalette(i,0  ,63 ,c  );top+=region;
  116. for (    c=0;i<top; i++,c+=dc) setrgbpalette(i,c  ,63 ,0  );top+=region;
  117. for (       ;i<=pointct;i++,c-=dc) setrgbpalette(i,63 ,c  ,0  );
  118.  
  119. cleardevice();
  120. }
  121.  
  122. reinit:
  123. //farmalloc room
  124. direction=malloc(POINTS*sizeof(unsigned char));
  125. xcoordinate=malloc(POINTS*sizeof(int));
  126. ycoordinate=malloc(POINTS*sizeof(int));
  127. destination=malloc(POINTS*sizeof(int));
  128. nextx=malloc(POINTS*sizeof(double));
  129. if (TLENGTH) {
  130.     trailx=farmalloc((long)POINTS*TLENGTH*sizeof(int));
  131.     traily=farmalloc((long)POINTS*TLENGTH*sizeof(int));
  132.     }
  133. if ((xcoordinate==NULL)||(ycoordinate==NULL)||(destination==NULL)||(nextx==NULL)||(TLENGTH&&((trailx==NULL)||(traily==NULL))))
  134.     {closegraph();printf("\nMemory error: try reducing POINTS or TLENGTH\n");getch();goto exit;}
  135.  
  136. //set-up initial position
  137. x=-(1+sqrt(1.-4.*CURVE))/2;
  138. dx=-2.*x/(POINTS+1);x+=dx;
  139. dirp=direction;xp=xcoordinate;yp=ycoordinate;destp=destination;nxp=nextx;
  140. for (i=0;i<POINTS;i++,dirp++,xp++,yp++,destp++,nxp++,x+=dx) {
  141.     *xp=MAP(x); *yp=-1;
  142.     *nxp=f(x);
  143.     *destp=size-MAP(*nxp);
  144.     UPORDOWN();
  145.     }
  146.  
  147. /*Init trails: the pointer method I use is rather memory hungry,
  148.   but its fast and, most of the time, for me anyway, the memory
  149.   hasn't been a problem.*/
  150. if (TLENGTH) {
  151.     txmax=trailx+(long)POINTS*TLENGTH-1;
  152.     for (tx=trailx,ty=traily;tx<=txmax;tx=tx+1,ty=tx+1) {*tx=-1;*ty=-1;}
  153.     tx=trailx;ty=traily;
  154.     }
  155.  
  156. replot:
  157. setwritemode(COPY_PUT);
  158.  
  159. //DRAW LINES
  160. setcolor(254);
  161. line(0,size>>1,size,size>>1);
  162. line(size>>1,0,size>>1,size);
  163. line(0,size,size,0);
  164.  
  165. //DRAW PARABOLA
  166. setcolor(255);
  167. i=0;
  168. moveto(i,size-MAP(f(UNMAP(i))));
  169. for (;i<size;i++)
  170.     lineto(i,size-MAP(f(UNMAP(i))));
  171.  
  172. repanel:
  173. setwritemode(COPY_PUT);
  174. //clear off the old panel
  175. if (!(panel==BIF&&obif!=-1)) {CLEARPANEL();}
  176. if (panel==TEXT) {                              //Draw the TEXT panel
  177.     unsigned char tstr[30];int col;
  178.     col=size+6;
  179.     settextjustify(LEFT_TEXT, CENTER_TEXT);
  180.     setcolor(254);
  181.     sprintf(tstr,"CURVE=%f",CURVE);outtextxy(col,(size>>1)-12,tstr);
  182.     sprintf(tstr,"POINTS=%i",POINTS);outtextxy(col,(size>>1),tstr);
  183.     sprintf(tstr,"TLENGTH=%i",TLENGTH);outtextxy(col,(size>>1)+12,tstr);
  184.     setcolor(255);
  185.     outtextxy(col,(size>>1)-94,"UP and DOWN");
  186.     outtextxy(col,(size>>1)-82,"  CURVE");
  187.     outtextxy(col,(size>>1)-66,"PGUP and PGDN");
  188.     outtextxy(col,(size>>1)-54,"  POINTS");
  189.     outtextxy(col,(size>>1)-38,"HOME and END");
  190.     outtextxy(col,(size>>1)-26,"  TLENGTH");
  191.     outtextxy(col,(size>>1)+26,"B=Bifurcation");
  192.     outtextxy(col,(size>>1)+40,"H=Hide Text");
  193.     outtextxy(col,(size>>1)+53,"T,S=Show Text");
  194.     outtextxy(col,(size>>1)+67,"C=Clear Trails");
  195.     outtextxy(col,(size>>1)+80,"P=Palette fix");
  196.     outtextxy(col,(size>>1)+94,"ALT-[A-E] VID");
  197.     }
  198. if (panel==BIF) { //                              Bifurcation Panel
  199.     int maxx, y=12, wx, cx;
  200.     double x, c=0, dc, mx;
  201.     unsigned char tstr[30];
  202.     setcolor(254);
  203.     settextjustify(LEFT_TEXT, TOP_TEXT);
  204.     setviewport(size, 0, getmaxx(), 11, 1);clearviewport();setviewport(0,0,getmaxx(),getmaxy(),1);
  205.     sprintf(tstr,"CURVE=%f",CURVE);outtextxy(size+6,0,tstr);
  206.     if (obif==-1) {
  207.         maxx=getmaxx();wx=maxx-size-1;cx=size+(wx>>1)+1;mx=(double)wx/4;
  208.         dc=-1./(double)((size-12)>>1);
  209.         while (y<size) {
  210.             for (i=1,x=0;i<=253;i++) {x=x*x+c;putpixel(cx+x*mx,y,i);}
  211.             for (i=1;i<=8;i++) {x=x*x+c;putpixel(cx+x*mx,y,255);}
  212.             y++;c+=dc;
  213.             }
  214.         }
  215.     setwritemode(XOR_PUT);
  216.     setcolor(255);
  217.     if (obif!=-1) line(size+1,obif,maxx,obif);//erase old line if applicable
  218.     obif=12-CURVE*((size-12)>>1);
  219.     line(size,obif,maxx,obif);                //plot new line
  220.     setwritemode(COPY_PUT);
  221.     }
  222.  
  223. cont:
  224. if (TLENGTH) setwritemode(XOR_PUT);
  225.  
  226. while (!kbhit()) { //MAIN LOOP
  227.     dirp=direction;xp=xcoordinate;yp=ycoordinate;destp=destination;nxp=nextx;
  228.     for (i=0;i<POINTS;dirp++,xp++,yp++,destp++,nxp++) {//cycle through the points
  229.         switch(*dirp) {
  230.         case UP:
  231.             (*yp)--;                    //go up
  232.             if (*yp<=*destp) {    //if we've reached our destination
  233.                 *destp=MAP(*nxp); //set our new destination
  234.                 LEFTORRIGHT();        //and figure out how to get there
  235.                 }
  236.             break;
  237.         case DOWN:
  238.             (*yp)++;
  239.             if (*yp>=*destp) {
  240.                 *destp=MAP(*nxp);
  241.                 LEFTORRIGHT();
  242.                 }
  243.             break;
  244.         case LEFT:
  245.             (*xp)--;
  246.             if (*xp<=*destp) {
  247.                 *nxp=f(*nxp);
  248.                 *destp=size-MAP(*nxp);
  249.                 UPORDOWN();
  250.                 }
  251.             break;
  252.         case RIGHT:
  253.             (*xp)++;
  254.             if (*xp>=*destp) {
  255.                 *nxp=f(*nxp);
  256.                 *destp=size-MAP(*nxp);
  257.                 UPORDOWN();
  258.                 }
  259.             break;
  260.         }
  261.         if (TLENGTH) {
  262.             putpixel(*xp,*yp,++i);
  263.             putpixel(*tx,*ty,i);
  264.             *tx=*xp;tx=tx+1;*ty=*yp;ty=ty+1;if (tx>txmax) {tx=trailx;ty=traily;}
  265.             }
  266.         else {
  267.             putpixel(*xp,*yp,(c+i)%253+1);i++;
  268.             }
  269.         }
  270.     if (++c>253) c=1;
  271.     }
  272.  
  273. skip:
  274. shift=*(unsigned char far *) 0x00000417L;//Access the keyboard shifts
  275. i=getch();
  276. if (i==0) i=getch()+256;
  277. switch(i) {
  278. case 27: goto exit;
  279. case 30+256: FREEMEM();obif=-1; cleardevice(); svgamodep=svgasetmode0;goto reinstall;//Alt- [A-E]
  280. case 48+256: FREEMEM();obif=-1; cleardevice(); svgamodep=svgasetmode1;goto reinstall;
  281. case 46+256: FREEMEM();obif=-1; cleardevice(); svgamodep=svgasetmode2;goto reinstall;
  282. case 32+256: FREEMEM();obif=-1; cleardevice(); svgamodep=svgasetmode3;goto reinstall;
  283. case 18+256: FREEMEM();obif=-1; cleardevice(); svgamodep=svgasetmode4;goto reinstall;
  284.  
  285. case '8': case 72+256: case 141+256:
  286.     if (shift&4) CURVE+=.001; else if (shift&3) CURVE+=.01; else CURVE+=.1;
  287.     if (CURVE>0) CURVE=0;
  288.     break;
  289. case '2': case 80+256: case 145+256:
  290.     if (shift&4) CURVE-=.001; else if (shift&3) CURVE-=.01; else CURVE-=.1;
  291.     if (CURVE<-2.) CURVE=-2.;
  292.     break;
  293. case '9': case 73+256: case 132+256:
  294.     if (shift&7) POINTS+=1; else POINTS+=10;
  295.     if (POINTS>253) POINTS=253;
  296.     break;
  297. case '3': case 81+256: case 118+256:
  298.     if (shift&7) POINTS-=1; else POINTS-=10;
  299.     if (POINTS<1) POINTS=1;
  300.     break;
  301. case '7': case 71+256: case 119+256:
  302.     if (shift&7) TLENGTH+=1; else TLENGTH+=10;
  303.     if (TLENGTH>253) TLENGTH=253;
  304.     break;
  305. case '1': case 79+256: case 117+256:
  306.     if (shift&7) TLENGTH-=1; else TLENGTH-=10;
  307.     if (TLENGTH<0) TLENGTH=0;
  308.     break;
  309. case 'p': case 'P': obif=-1;cleardevice();
  310.     FREEMEM();
  311.     goto redraw;
  312. case 't': case 'T': case 's': case 'S': panel=TEXT;  goto repanel;
  313. case 'b': case 'B': obif=-1;            panel=BIF;   goto repanel;
  314. case 'h': case 'H':                     panel=HIDDEN;goto repanel;
  315. case 'c': case 'C':
  316.     if (TLENGTH==0) {
  317.         CLEARMAIN();
  318.         goto replot;
  319.         }
  320. default: goto cont;
  321. }
  322. FREEMEM();
  323. if (kbhit()) goto skip;
  324. CLEARMAIN();
  325. goto reinit;
  326.  
  327. exit:
  328. closegraph();
  329. printf("\
  330. \n\
  331. \t\t    --==≡≡    O R B I T    W H I R L    ≡≡==--\n\
  332. \tFreeWare by Marc Coram (thanks to Jordan Hargrave for SVGA256.BGI)\n\
  333.   --Based on the orbits of the Mandelbrot Set for real numbers (VGA REQUIRED)--\n\
  334. \n\
  335. Syntax: ORBWHIRL [VIDMODE ][CURVE [POINTS [TLENGTH]]]\n\
  336. \tVIDMODE is a letter A-E which selects your video mode.\n\
  337. \t\tA=320x200 B=640x400 C=640x480 D=800x600 E=1024x768\n\
  338. \tCURVE   is a floating point number between -2 and 0 It signifies C\n\
  339. \t\tin the iterative formula nx=x*x+C, whose graph is the parabola.\n\
  340. \t\tAs CURVE approaches 0, the parabola raises and the pattern\n\
  341. \t\tbecomes regular. As CURVE approaches -2, the curve drops and\n\
  342. \t\tthe pattern becomes chaotic.\n\
  343. \tPOINTS  is an integer which signifies how many individual tracing\n\
  344. \t\tswirls will be produced ( <=253 ). Lower POINTS for speed.\n\
  345. \tTLENGTH is an integer which signifies the length of the tracing swirls.\n\
  346. \t\tIf zero, the trails will not clear.\n\
  347. \n\
  348. Default:  \"ORBWHIRL A -2 100 8\"\n\
  349. Also try: \"ORBWHIRL -1.4 25 1000\" OR \"ORBWHIRL -.72\" OR \"ORBWHIRL -1.7 60 50\"\n\
  350. \t  \"ORBWHIRL B -2 253 0\" OR \"ORBWHIRL D\" OR \"ORBWHIRL -1.75 2 0\"\n\
  351. \n\
  352. ENJOY!\tComments/Improvements(/Donations?) appreciated:\n\
  353. \tMarc Coram / 15570 Knochaven Rd / Santa Clarita, CA 91350-2799\
  354. ");
  355. }
  356.